home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / text / edit / Smartindent.lha / Smartindent / Source / dispatcher.c < prev    next >
C/C++ Source or Header  |  1997-12-14  |  6KB  |  301 lines

  1. /*(( "Kopf" */
  2. /* -----------------------------------------------------------------------------
  3.  
  4.    $Id: dispatcher.c,v 1.4 1997/06/26 14:34:53 mshopf Exp mshopf $
  5.  
  6.    GoldED API client, ©1997 Matthias Hopf.
  7.    Compiled with SasC.
  8.  
  9.  
  10.    Function dispatcher.
  11.  
  12.    ------------------------------------------------------------------------------
  13. */
  14.  
  15. /*)) */
  16. /*(( "Includes" */
  17.  
  18. #include "smartindent.h"
  19. #include "dispatcher.h"
  20. #include "util.h"
  21.  
  22. #include <proto/dos.h>
  23. #include <proto/intuition.h>
  24.  
  25. #include <exec/types.h>
  26. #include <dos/dos.h>
  27. #include <intuition/intuition.h>
  28.  
  29. #include <string.h>
  30.  
  31. /*)) */
  32.  
  33. /*(( "Template" */
  34.  
  35. static char *MainTemplate = "MODE/K,DEBUG/N/K,CONFIG/M/N/K";
  36.  
  37. /*)) */
  38.  
  39. /********** Private **********/
  40. /*(( "DoIndentation ()" */
  41.  
  42. static char *DoIndentation (sc_t *c, int BeginLine, int EndLine, int Mode)
  43. {
  44.     InitIndent (c, BeginLine, EndLine, Mode);
  45.     (*c->Sem->Indent) (c);
  46.  
  47.     CleanupIndent (c);
  48.     return (c->ErrTxt);
  49. }
  50.  
  51.  
  52. /*)) */
  53. /*(( "Cmd_SmartIndent ()" */
  54.  
  55. static char *Cmd_SmartIndent (sc_t *c, struct APIMessage *msg, LONG *args)
  56. {
  57.     int                Mode      = 0;
  58.     int Start, End;
  59.     struct EditConfig *Edit = c->Edit;
  60.  
  61.     Start = Edit->Line;
  62.     End   = Edit->Line - 1;
  63.  
  64.     if (args[0])
  65.     {
  66.     Mode |= MODE_LINE;
  67.     End   = Edit->Line;
  68.     }
  69.     if (args[1])
  70.     {
  71.     Mode |= MODE_LASTLINE;
  72.     Start = Edit->Line - 1;
  73.     }
  74.     if (args[2])
  75.     {
  76.     Mode |= MODE_CURSOR;
  77.     }
  78.     if (args[3])
  79.     {
  80.     Mode |= MODE_BLOCK;
  81.     Start = Edit->BlockStartY;
  82.     End   = Edit->BlockEndY;
  83.     if (Edit->Marker == BLOCKMODE_NONE)
  84.         return ("No block specified");
  85.     }
  86.  
  87.     if (Mode == 0)
  88.     return ("No mode specified");
  89.  
  90.     return (DoIndentation (c, Start, End, Mode));
  91. }
  92.  
  93.  
  94. /*)) */
  95.  
  96. /********** Public **********/
  97. /*(( "ScanArgs ()" */
  98.  
  99. /* Scan startup arguments, return Mode, when sucessfull */
  100.  
  101. char *ScanArgs (sc_t *c, char *cmd, struct APIMessage *msg)
  102. {
  103.     struct RDArgs *rdArgs, *args;
  104.     const char    *Mode = NULL, *Error = NULL;
  105.  
  106.     if ( (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) )
  107.     {
  108.     char  Buffer [80 +1];
  109.     LONG  argArray[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  110.     short *cp;
  111.     long  **p;
  112.     struct Semantic **s;
  113.  
  114.         /* make LF-terminated copy of command string (required by dos/readArgs): */
  115.  
  116.     strncpy (Buffer, cmd, sizeof (Buffer)-2);
  117.     strcat  (Buffer, "\12");
  118.  
  119.     rdArgs->RDA_Source.CS_Buffer = Buffer;
  120.     rdArgs->RDA_Source.CS_Length = strlen (Buffer);
  121.  
  122.     if ( (args = ReadArgs (MainTemplate, argArray, rdArgs)) )
  123.     {
  124.         if (argArray [0])
  125.         {
  126.         Mode = ((char **) argArray) [0];
  127.         for (s = Semantics; *s; s++)
  128.         {
  129.             if (strcasecmp (Mode, (*s)->Name) == 0)
  130.             c->Sem = *s;
  131.         }
  132.         if (! c->Sem)
  133.             Error = UNKNOWN_MODE_ERROR;
  134.         }
  135.         else
  136.         Error = UNSPECIFIED_MODE_ERROR;
  137.         /* TODO: dynamic type detection when MODE/K is not given */
  138.  
  139. #ifdef DEBUG
  140.         if (argArray [1])
  141.         Dbug = * ((long **) argArray) [1];
  142. #endif
  143.         /* create configuration */
  144.         memcpy (&(c->Conf), &(c->Sem->StartConf), sizeof (struct SmartConfig));
  145.         if (argArray [2])
  146.         {
  147.         p  = ((long ***) argArray) [2];
  148.         for (cp = (short *) &(c->Conf); cp < (short *) (&(c->Conf) + 1); cp++)
  149.             if (*p)
  150.             *cp = **p++;
  151.             else
  152.             break;
  153.         }
  154.  
  155.         FreeArgs(args);
  156.     }
  157.     else
  158.     {
  159.         Fault (IoErr(), MainTemplate, Buffer, sizeof (Buffer)-1);
  160.         Error = Buffer;
  161.     }
  162.  
  163.     FreeDosObject(DOS_RDARGS, rdArgs);
  164.     }
  165.     else
  166.     Error = "AllocDosObject() failed";
  167.  
  168.     if (Error)                          /* an error occured */
  169.     {
  170.     struct EasyStruct es = { sizeof (struct EasyStruct), NULL, "Smartindent error", NULL, "Ok" };
  171.  
  172.     es.es_TextFormat = (char *) Error;
  173.     EasyRequest (NULL, &es, NULL, NULL);
  174.     return NULL;
  175.     }
  176.  
  177.     return Mode;
  178. }
  179.  
  180.  
  181. /*)) */
  182. /*(( "DispatchKey ()" */
  183.  
  184. void DispatchKey (sc_t *c, struct APIMessage *msg)
  185. {
  186. #ifdef DEBUG
  187.     char k [2];
  188.     extern Dbug_Counter;
  189.     Dbug_Counter = 0;
  190.     k [0] = (int) msg->api_Data;
  191.     k [1] = 0;
  192.     debug (D_KEY, ("Keycode 0x%lx, '%s'\n", (long) msg->api_Data, k));
  193. #endif
  194.  
  195.     c->Edit = (struct EditConfig *) msg->api_Instance->api_Environment;
  196.     c->Msg  = msg;
  197.  
  198.     (*c->Sem->KeyPress) (c, (int) msg->api_Data);
  199.  
  200.     msg->api_RC = RC_OK;
  201.     if ( (msg->api_CommandError = c->ErrTxt) )
  202.     msg->api_RC = RC_WARN;
  203. }
  204.  
  205.  
  206. /*)) */
  207. /*(( "DispatchCmd ()" */
  208.  
  209. void DispatchCmd (sc_t *client, struct APIMessage *msg)
  210. {
  211.     struct RDArgs *rdArgs, *args;
  212.  
  213. #ifdef DEBUG
  214.     extern Dbug_Counter;
  215.     Dbug_Counter = 0;
  216. #endif
  217.  
  218.     client->Edit = (struct EditConfig *) msg->api_Instance->api_Environment;
  219.     client->Msg  = msg;
  220.  
  221.     if ( (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) )
  222.     {
  223.     ULONG n;
  224.     char  buffer [80];
  225.     LONG argArray[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  226.  
  227.         // make LF-terminated copy of command string (required by dos/readArgs):
  228.  
  229.     strncpy (buffer, msg->api_Command, sizeof(buffer));
  230.     strcat  (buffer, "\12");
  231.  
  232.     for (n = 0; Parser[n].Cmd; n++)
  233.     {
  234.         if (memcmp(buffer, Parser[n].Cmd, strlen(Parser[n].Cmd)) == 0)
  235.         {
  236.         UBYTE *arguments = buffer + strlen(Parser[n].Cmd);
  237.  
  238.             // tell host that message has been consumed by us:
  239.  
  240.         msg->api_State = API_STATE_CONSUMED;
  241.         msg->api_RC    = RC_OK;
  242.  
  243.         rdArgs->RDA_Source.CS_Buffer = arguments;
  244.         rdArgs->RDA_Source.CS_Length = strlen(arguments);
  245.         rdArgs->RDA_Source.CS_CurChr = 0;
  246.         rdArgs->RDA_DAList           = NULL;
  247.         rdArgs->RDA_Buffer           = NULL;
  248.  
  249.         if (Parser[n].Template)
  250.         {
  251.             if ( (args = ReadArgs(Parser[n].Template, argArray, rdArgs)) )
  252.             {
  253.             if ( (msg->api_CommandError = (*Parser[n].Handler)(client, msg, argArray)) )
  254.                 msg->api_RC = RC_WARN;
  255.             FreeArgs(args);
  256.             }
  257.             else {
  258.             static UBYTE errorText[80 + 1];
  259.             msg->api_RC           = RC_WARN;
  260.             msg->api_CommandError = errorText;
  261.             Fault(IoErr(), "IoErr()", errorText, 80);
  262.             }
  263.         }
  264.         else
  265.         {
  266.             if ( (msg->api_CommandError = (*Parser[n].Handler)(client, msg, argArray)) )
  267.             msg->api_RC = RC_WARN;
  268.         }
  269.  
  270.         break;
  271.         }
  272.     }
  273.  
  274.     FreeDosObject(DOS_RDARGS, rdArgs);
  275.     }
  276. }
  277.  
  278.  
  279. /*)) */
  280.  
  281. /*(( "Dispatchlists" */
  282.  
  283. char *apiCommands[] = { "SMARTINDENT LINE/S,LASTLINE/S,CURSOR/S,BLOCK/S", NULL };
  284.  
  285. struct Parser Parser[] =
  286. {
  287.     /*
  288.      * SMARTINDENT:
  289.      *     LINE:     indent current line
  290.      *     LASTLINE: indent line above cursor
  291.      *     CURSOR:   Set Cursorpos to indentation position
  292.      *     BLOCK:    indent marked block
  293.      */
  294.     "SMARTINDENT", Cmd_SmartIndent, "LINE/S,LASTLINE/S,CURSOR/S,BLOCK/S",
  295.  
  296.     NULL
  297. } ;
  298.  
  299. /*)) */
  300.  
  301.